package com.lazily.innerclass;


/**
 * @Author: GZQ
 * @date: 2025/2/15 15:17
 * @description: 演示匿名内部类的使用(重要 ! ! ! !)🪶🪶🪶🪶🪶
 */

public class AnonymousInnerClass {
	// 程序入口
	public static void main(String[] args) {
		Outer04 outer04 = new Outer04();
		outer04.method();
	}
}


class Outer04 { // 外部类
	private int n1 = 10; // 属性

	public void method() { // 方法
		// 基于接口的匿名内部类
		/*
		1. 需求：想使用IA接口, 并创建对象
		2. 传统方式,是写一个类, 实现该接口, 并创建对象
		3. 现在需求 Tiger/Dog 类只使用一次, 后面再不使用
		4. 此时可以使用匿名类部类来简化开发
		5. tiger 的编译类型 ? IA
		6. tiger 的运行类型 ? 就是匿名内部类 XXX => Outer04$1
		// 我们看底层 会分配 类名 Outer04$1
		class XXXX implements IA ｛
			@Override
			public void cry() {
				System.out.println("老虎叫唤....");
			}
		｝

		* */
		// 7. jdk底层创建匿名内部类 Outer04$1, 立即马上就创建了 Outer04$1实例, 并且把地址
		// 返回给 tiger
		// 8. 匿名内部类使用一次, 就不能在使用
		IA tiger = new IA() {
			@Override
			public void cry() {
				System.out.println("老虎叫唤....");
			}
		};
		System.out.println("tiger的运行类型=" + tiger.getClass());
		tiger.cry();
		tiger.cry();
		tiger.cry();
		tiger.cry();

		// IA tiger = new Tiger();
		// tiger.cry();

		// 演示基于类的匿名内部类
		// 分析
		// 1. father 编译类型 Father
		// 2. father 运行类型 Outer04$2
		// 3. 底层会创建匿名内部类
		/*
			class Outer04$2 extends Father {
				@Override
				public void  test() {
					System.out.println("匿名内部类重写了test方法");
				}
			}
		 */
		// 4. 同时也直接返回了 匿名内部类 Outer04$2的对象
		// 5. 注意("jack") 参数列表会传递给 构造器
		Father father = new Father("jack") {
			@Override
			public void test() {
				System.out.println("匿名内部类重写了test方法");
			}
		};
		System.out.println("fanter对象的运行类型=" + father.getClass()); // Outer04$2
		father.test();

		// 基于抽象类的匿名内部类
		Animial animial = new Animial() {
			@Override
			void eat() {
				System.out.println("小狗吃骨头....");
			}
		};
		animial.eat();
	}
}

interface IA { // 接口
	public void cry();
}

// class Tiger implements IA {
//
// 	@Override
// 	public void cry() {
// 		System.out.println("老虎叫唤....");
// 	}
// }
//
// class Dog implements IA {
//
// 	@Override
// 	public void cry() {
// 		System.out.println("小狗汪汪叫....");
// 	}
// }

class Father { // 类
	public Father(String name) { // 构造器
		System.out.println("接收到name=" + name);
	}

	public void test() { // 方法

	}
}

abstract class Animial { // 抽象类
	abstract void eat();
}